package com.softdev.system.generator.controller;

import com.alibaba.fastjson.JSONObject;
import com.softdev.system.generator.entity.ClassInfo;
import com.softdev.system.generator.entity.ReturnT;
import com.softdev.system.generator.util.FreemarkerTool;
import com.softdev.system.generator.util.HttpClientUtil;
import com.softdev.system.generator.util.TableParseUtil;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * spring boot code generator
 * @author zhengk/moshow
 */
@Controller
@Slf4j
public class IndexController {

    @Autowired
    private FreemarkerTool freemarkerTool;

    @RequestMapping("/")
    public String index() {
        return "index";
    }

    @RequestMapping("/genCode")
    @ResponseBody
    public ReturnT<Map<String, String>> codeGenerate(String tableSql,
        //2019-2-10 liutf 修改为@RequestParam参数校验
        @RequestParam(required = false, defaultValue = "penghj") String authorName,
        @RequestParam(required = false, defaultValue = "com.softdev.system") String packageName,
        @RequestParam(required = false, defaultValue = "ApiReturnUtil") String returnUtil,
        @RequestParam(required = false, defaultValue = "true") boolean isUnderLineToCamelCase,
        @RequestParam(required = false, defaultValue = "boolean") String tinyintTransType) {

        try {
            // parse table
            ClassInfo classInfo =
                TableParseUtil.processTableIntoClassInfo(tableSql, isUnderLineToCamelCase, tinyintTransType);

            // code genarete
            Map<String, Object> params = new HashMap<String, Object>(8);
            params.put("classInfo", classInfo);
            params.put("authorName", authorName);
            params.put("packageName", packageName);
            params.put("returnUtil", returnUtil);

            // result
            Map<String, String> result = new HashMap<String, String>(32);

            //UI
            // result.put("swagger-ui", freemarkerTool.processString("code-generator/ui/swagger-ui.ftl", params));
            // result.put("element-ui", freemarkerTool.processString("code-generator/ui/element-ui.ftl", params));
            // result.put("bootstrap-ui", freemarkerTool.processString("code-generator/ui/bootstrap-ui.ftl", params));
            //mybatis old
            result.put("controller", freemarkerTool.processString("code-generator/mybatis/controller.ftl", params));
            result.put("service", freemarkerTool.processString("code-generator/mybatis/service.ftl", params));
            result.put("service_impl", freemarkerTool.processString("code-generator/mybatis/service_impl.ftl", params));
            result.put("mapper", freemarkerTool.processString("code-generator/mybatis/dao.ftl", params));
            result.put("mybatis", freemarkerTool.processString("code-generator/mybatis/daoXml.ftl", params));
            // result.put("model", freemarkerTool.processString("code-generator/mybatis/model.ftl", params));
            //jpa
            // result.put("entity", freemarkerTool.processString("code-generator/jpa/entity.ftl", params));
            // result.put("repository", freemarkerTool.processString("code-generator/jpa/repository.ftl", params));
            // result.put("jpacontroller", freemarkerTool.processString("code-generator/jpa/jpacontroller.ftl", params));
            //jdbc template
            // result.put("jtdao", freemarkerTool.processString("code-generator/jdbc-template/jtdao.ftl", params));
            // result.put("jtdaoimpl", freemarkerTool.processString("code-generator/jdbc-template/jtdaoimpl.ftl", params));
            //beetsql
            // result.put("beetlmd", freemarkerTool.processString("code-generator/beetlsql/beetlmd.ftl", params));
            result.put("beetlentity", freemarkerTool.processString("code-generator/mybatis/beetlentity.ftl", params));
            // result.put("beetlentitydto", freemarkerTool.processString("code-generator/beetlsql/beetlentitydto.ftl", params));
            // result.put("beetlcontroller", freemarkerTool.processString("code-generator/beetlsql/beetlcontroller.ftl", params));
            //mybatis plus
            // result.put("pluscontroller", freemarkerTool.processString("code-generator/mybatis-plus/pluscontroller.ftl", params));
            // result.put("plusmapper", freemarkerTool.processString("code-generator/mybatis-plus/plusmapper.ftl", params));
            //util
            // result.put("util", freemarkerTool.processString("code-generator/util/util.ftl", params));
            //sql generate
            // result.put("select", freemarkerTool.processString("code-generator/sql/select.ftl", params));
            // result.put("insert", freemarkerTool.processString("code-generator/sql/insert.ftl", params));
            // result.put("update", freemarkerTool.processString("code-generator/sql/update.ftl", params));
            // result.put("delete", freemarkerTool.processString("code-generator/sql/delete.ftl", params));

            // 计算,生成代码行数
            int lineNum = 0;
            for (Map.Entry<String, String> item : result.entrySet()) {
                if (item.getValue() != null) {
                    lineNum += StringUtils.countMatches(item.getValue(), "\n");
                }
            }
            log.info("生成代码行数：{}", lineNum);
            //测试环境可自行开启
            //log.info("生成代码数据：{}", result);
            return new ReturnT<>(result);
        } catch (IOException | TemplateException e) {
            log.error(e.getMessage(), e);
            return new ReturnT<>(ReturnT.FAIL_CODE, "表结构解析失败" + e.getMessage());
        }

    }

    @RequestMapping("/saveFile")
    @ResponseBody
    public boolean saveFile(String tableSql, @RequestParam(required = false, defaultValue = "penghj") String authorName,
        @RequestParam(required = false, defaultValue = "com.zw.test") String packageName,
        @RequestParam(required = false, defaultValue = "ApiReturnUtil") String returnUtil,
        @RequestParam(required = false, defaultValue = "true") boolean isUnderLineToCamelCase,
        @RequestParam(required = false, defaultValue = "boolean") String tinyintTransType) {
        try {
            String[] strArr = new String[] { "beetlentity", "dao", "service", "service_impl", "controller" };
            String[] sqlArr = tableSql.split("--tableSeparateRegex--");
            Map<String, Object> params = new HashMap<String, Object>(8);
            params.put("authorName", authorName);
            params.put("packageName", packageName);
            params.put("returnUtil", returnUtil);
            String dir1 = "D:/sql生成";
            File dirFile1 = new File(dir1);
            if (!dirFile1.exists()) {
                dirFile1.mkdir();
            }
            for (String sql : sqlArr) {
                ClassInfo classInfo =
                    TableParseUtil.processTableIntoClassInfo(sql, isUnderLineToCamelCase, tinyintTransType);
                params.put("classInfo", classInfo);
                String tableName = classInfo.getTableName();
                String dir = "D:/sql生成/" + tableName;
                File dirFile = new File(dir);
                if (!dirFile.exists()) {
                    dirFile.mkdir();
                }
                String mybatisName = "";
                for (String key : strArr) {
                    String beetlentity = freemarkerTool.processString("code-generator/mybatis/"+key+".ftl", params);
                    if (Objects.equals(key, "mapper")) {
                        beetlentity = beetlentity.replace("Mapper ", "Dao ");
                    }
                    int b = beetlentity.indexOf("public");
                    int b1 = beetlentity.indexOf(" ", b + 1);
                    int b2 = beetlentity.indexOf(" ", b1 + 1);
                    int b3 = beetlentity.indexOf(" ", b2 + 1);
                    String className = beetlentity.substring(b2 + 1, b3);
                    if (Objects.equals(key, "dao")) {
                        mybatisName = className + ".xml";
                    }
                    String fileName = dir + "/" + className + ".java";
                    File nameFile = new File(fileName);
                    if (!nameFile.exists()) {
                        nameFile.createNewFile();
                    }
                    FileOutputStream fileOutputStream = new FileOutputStream(nameFile, true);
                    fileOutputStream.write(beetlentity.getBytes("utf-8"));
                    fileOutputStream.close();
                }
                String beetlentity = freemarkerTool.processString("code-generator/mybatis/daoXml.ftl", params);
                File nameFile = new File(dir + "/" + mybatisName);
                if (!nameFile.exists()) {
                    nameFile.createNewFile();
                }
                FileOutputStream fileOutputStream = new FileOutputStream(nameFile, true);
                fileOutputStream.write(beetlentity.getBytes("utf-8"));
                fileOutputStream.close();
            }
            return true;
        } catch (Exception e) {
            log.error("存储文件异常", e);
        }
        return false;
    }

}
